var Node = Node || {
  ELEMENT_NODE: 1,
  ATTRIBUTE_NODE: 2,
  TEXT_NODE: 3
};

$.scrollWindowTo = function(pos, duration, cb) {
  if (duration == null) {
    duration = 0;
  }
  if (pos === $(window).scrollTop()) {
    $(window).trigger('scroll');
    if (typeof cb === "function") {
      cb();
    }
    return;
  }
  return $('html, body').animate({
    scrollTop: pos
  }, duration, function() {
    return typeof cb === "function" ? cb() : void 0;
  });
};

/*jshint expr:true eqnull:true */
/**
 *
 * Backbone.DeepModel v0.10.4
 *
 * Copyright (c) 2013 Charles Davison, Pow Media Ltd
 *
 * https://github.com/powmedia/backbone-deep-model
 * Licensed under the MIT License
 */

/**
 * Underscore mixins for deep objects
 *
 * Based on https://gist.github.com/echong/3861963
 */
(function() {
  var arrays, basicObjects, deepClone, deepExtend, deepExtendCouple, isBasicObject,
    __slice = [].slice;

  deepClone = function(obj) {
    var func, isArr;
    if (!_.isObject(obj) || _.isFunction(obj)) {
      return obj;
    }
    if (obj instanceof Backbone.Collection || obj instanceof Backbone.Model) {
      return obj;
    }
    if (_.isDate(obj)) {
      return new Date(obj.getTime());
    }
    if (_.isRegExp(obj)) {
      return new RegExp(obj.source, obj.toString().replace(/.*\//, ""));
    }
    isArr = _.isArray(obj || _.isArguments(obj));
    func = function(memo, value, key) {
      if (isArr) {
        memo.push(deepClone(value));
      } else {
        memo[key] = deepClone(value);
      }
      return memo;
    };
    return _.reduce(obj, func, isArr ? [] : {});
  };

  isBasicObject = function(object) {
    if (object == null) return false;
    return (object.prototype === {}.prototype || object.prototype === Object.prototype) && _.isObject(object) && !_.isArray(object) && !_.isFunction(object) && !_.isDate(object) && !_.isRegExp(object) && !_.isArguments(object);
  };

  basicObjects = function(object) {
    return _.filter(_.keys(object), function(key) {
      return isBasicObject(object[key]);
    });
  };

  arrays = function(object) {
    return _.filter(_.keys(object), function(key) {
      return _.isArray(object[key]);
    });
  };

  deepExtendCouple = function(destination, source, maxDepth) {
    var combine, recurse, sharedArrayKey, sharedArrayKeys, sharedObjectKey, sharedObjectKeys, _i, _j, _len, _len1;
    if (maxDepth == null) {
      maxDepth = 20;
    }
    if (maxDepth <= 0) {
      console.warn('_.deepExtend(): Maximum depth of recursion hit.');
      return _.extend(destination, source);
    }
    sharedObjectKeys = _.intersection(basicObjects(destination), basicObjects(source));
    recurse = function(key) {
      return source[key] = deepExtendCouple(destination[key], source[key], maxDepth - 1);
    };
    for (_i = 0, _len = sharedObjectKeys.length; _i < _len; _i++) {
      sharedObjectKey = sharedObjectKeys[_i];
      recurse(sharedObjectKey);
    }
    sharedArrayKeys = _.intersection(arrays(destination), arrays(source));
    combine = function(key) {
      return source[key] = _.union(destination[key], source[key]);
    };
    for (_j = 0, _len1 = sharedArrayKeys.length; _j < _len1; _j++) {
      sharedArrayKey = sharedArrayKeys[_j];
      combine(sharedArrayKey);
    }
    return _.extend(destination, source);
  };

  deepExtend = function() {
    var finalObj, maxDepth, objects, _i;
    objects = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), maxDepth = arguments[_i++];
    if (!_.isNumber(maxDepth)) {
      objects.push(maxDepth);
      maxDepth = 20;
    }
    if (objects.length <= 1) {
      return objects[0];
    }
    if (maxDepth <= 0) {
      return _.extend.apply(this, objects);
    }
    finalObj = objects.shift();
    while (objects.length > 0) {
      finalObj = deepExtendCouple(finalObj, deepClone(objects.shift()), maxDepth);
    }
    return finalObj;
  };

  _.mixin({
    deepClone: deepClone,
    isBasicObject: isBasicObject,
    basicObjects: basicObjects,
    arrays: arrays,
    deepExtend: deepExtend
  });

}).call(this);

/**
 * Main source
 */

;(function(factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['underscore', 'backbone'], factory);
    } else {
        // globals
        factory(_, Backbone);
    }
}(function(_, Backbone) {
    
    /**
     * Takes a nested object and returns a shallow object keyed with the path names
     * e.g. { "level1.level2": "value" }
     *
     * @param  {Object}      Nested object e.g. { level1: { level2: 'value' } }
     * @return {Object}      Shallow object with path names e.g. { 'level1.level2': 'value' }
     */
    function objToPaths(obj) {
        var ret = {},
            separator = DeepModel.keyPathSeparator;

        for (var key in obj) {
            var val = obj[key];

            if (val && val.constructor === Object && !_.isEmpty(val)) {
                //Recursion for embedded objects
                var obj2 = objToPaths(val);

                for (var key2 in obj2) {
                    var val2 = obj2[key2];

                    ret[key + separator + key2] = val2;
                }
            } else {
                ret[key] = val;
            }
        }

        return ret;
    }

    /**
     * @param {Object}  Object to fetch attribute from
     * @param {String}  Object path e.g. 'user.name'
     * @return {Mixed}
     */
    function getNested(obj, path, return_exists) {
        var separator = DeepModel.keyPathSeparator;

        var fields = path.split(separator);
        var result = obj;
        return_exists || (return_exists === false);
        for (var i = 0, n = fields.length; i < n; i++) {
            if (return_exists && !_.has(result, fields[i])) {
                return false;
            }
            result = result[fields[i]];

            if (result == null && i < n - 1) {
                result = {};
            }
            
            if (typeof result === 'undefined') {
                if (return_exists)
                {
                    return true;
                }
                return result;
            }
        }
        if (return_exists)
        {
            return true;
        }
        return result;
    }

    /**
     * @param {Object} obj                Object to fetch attribute from
     * @param {String} path               Object path e.g. 'user.name'
     * @param {Object} [options]          Options
     * @param {Boolean} [options.unset]   Whether to delete the value
     * @param {Mixed}                     Value to set
     */
    function setNested(obj, path, val, options) {
        options = options || {};

        var separator = DeepModel.keyPathSeparator;

        var fields = path.split(separator);
        var result = obj;
        for (var i = 0, n = fields.length; i < n && result !== undefined ; i++) {
            var field = fields[i];

            //If the last in the path, set the value
            if (i === n - 1) {
                options.unset ? delete result[field] : result[field] = val;
            } else {
                //Create the child object if it doesn't exist, or isn't an object
                if (typeof result[field] === 'undefined' || ! _.isObject(result[field])) {
                    result[field] = {};
                }

                //Move onto the next part of the path
                result = result[field];
            }
        }
    }

    function deleteNested(obj, path) {
      setNested(obj, path, null, { unset: true });
    }

    var DeepModel = Backbone.Model.extend({

        // Override constructor
        // Support having nested defaults by using _.deepExtend instead of _.extend
        constructor: function(attributes, options) {
            var defaults;
            var attrs = attributes || {};
            this.cid = _.uniqueId('c');
            this.attributes = {};
            if (options && options.collection) this.collection = options.collection;
            if (options && options.parse) attrs = this.parse(attrs, options) || {};
            if (defaults = _.result(this, 'defaults')) {
                //<custom code>
                // Replaced the call to _.defaults with _.deepExtend.
                attrs = _.deepExtend({}, defaults, attrs);
                //</custom code>
            }
            this.set(attrs, options);
            this.changed = {};
            this.initialize.apply(this, arguments);
        },

        // Return a copy of the model's `attributes` object.
        toJSON: function(options) {
          return _.deepClone(this.attributes);
        },

        // Override get
        // Supports nested attributes via the syntax 'obj.attr' e.g. 'author.user.name'
        get: function(attr) {
            return getNested(this.attributes, attr);
        },

        // Override set
        // Supports nested attributes via the syntax 'obj.attr' e.g. 'author.user.name'
        set: function(key, val, options) {
            var attr, attrs, unset, changes, silent, changing, prev, current;
            if (key == null) return this;
            
            // Handle both `"key", value` and `{key: value}` -style arguments.
            if (typeof key === 'object') {
              attrs = key;
              options = val || {};
            } else {
              (attrs = {})[key] = val;
            }

            options || (options = {});
            
            // Run validation.
            if (!this._validate(attrs, options)) return false;

            // Extract attributes and options.
            unset           = options.unset;
            silent          = options.silent;
            changes         = [];
            changing        = this._changing;
            this._changing  = true;

            if (!changing) {
              this._previousAttributes = _.deepClone(this.attributes); //<custom>: Replaced _.clone with _.deepClone
              this.changed = {};
            }
            current = this.attributes, prev = this._previousAttributes;

            // Check for changes of `id`.
            if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];

            //<custom code>
            attrs = objToPaths(attrs);
            //</custom code>

            // For each `set` attribute, update or delete the current value.
            for (attr in attrs) {
              val = attrs[attr];

              //<custom code>: Using getNested, setNested and deleteNested
              if (!_.isEqual(getNested(current, attr), val)) changes.push(attr);
              if (!_.isEqual(getNested(prev, attr), val)) {
                setNested(this.changed, attr, val);
              } else {
                deleteNested(this.changed, attr);
              }
              unset ? deleteNested(current, attr) : setNested(current, attr, val);
              //</custom code>
            }

            // Trigger all relevant attribute changes.
            if (!silent) {
              if (changes.length) this._pending = true;

              //<custom code>
              var separator = DeepModel.keyPathSeparator;

              for (var i = 0, l = changes.length; i < l; i++) {
                var key = changes[i];

                this.trigger('change:' + key, this, getNested(current, key), options);

                var fields = key.split(separator);

                //Trigger change events for parent keys with wildcard (*) notation
                for(var n = fields.length - 1; n > 0; n--) {
                  var parentKey = _.first(fields, n).join(separator),
                      wildcardKey = parentKey + separator + '*';

                  this.trigger('change:' + wildcardKey, this, getNested(current, parentKey), options);
                }
                //</custom code>
              }
            }

            if (changing) return this;
            if (!silent) {
              while (this._pending) {
                this._pending = false;
                this.trigger('change', this, options);
              }
            }
            this._pending = false;
            this._changing = false;
            return this;
        },

        // Clear all attributes on the model, firing `"change"` unless you choose
        // to silence it.
        clear: function(options) {
          var attrs = {};
          var shallowAttributes = objToPaths(this.attributes);
          for (var key in shallowAttributes) attrs[key] = void 0;
          return this.set(attrs, _.extend({}, options, {unset: true}));
        },

        // Determine if the model has changed since the last `"change"` event.
        // If you specify an attribute name, determine if that attribute has changed.
        hasChanged: function(attr) {
          if (attr == null) return !_.isEmpty(this.changed);
          return getNested(this.changed, attr) !== undefined;
        },

        // Return an object containing all the attributes that have changed, or
        // false if there are no changed attributes. Useful for determining what
        // parts of a view need to be updated and/or what attributes need to be
        // persisted to the server. Unset attributes will be set to undefined.
        // You can also pass an attributes object to diff against the model,
        // determining if there *would be* a change.
        changedAttributes: function(diff) {
          //<custom code>: objToPaths
          if (!diff) return this.hasChanged() ? objToPaths(this.changed) : false;
          //</custom code>

          var old = this._changing ? this._previousAttributes : this.attributes;
          
          //<custom code>
          diff = objToPaths(diff);
          old = objToPaths(old);
          //</custom code>

          var val, changed = false;
          for (var attr in diff) {
            if (_.isEqual(old[attr], (val = diff[attr]))) continue;
            (changed || (changed = {}))[attr] = val;
          }
          return changed;
        },

        // Get the previous value of an attribute, recorded at the time the last
        // `"change"` event was fired.
        previous: function(attr) {
          if (attr == null || !this._previousAttributes) return null;

          //<custom code>
          return getNested(this._previousAttributes, attr);
          //</custom code>
        },

        // Get all of the attributes of the model at the time of the previous
        // `"change"` event.
        previousAttributes: function() {
          //<custom code>
          return _.deepClone(this._previousAttributes);
          //</custom code>
        }
    });


    //Config; override in your app to customise
    DeepModel.keyPathSeparator = '.';


    //Exports
    Backbone.DeepModel = DeepModel;

    //For use in NodeJS
    if (typeof module != 'undefined') module.exports = DeepModel;
    
    return Backbone;

}));



//Rivets.js
//version: 0.5.13
//author: Michael Richards
//license: MIT
(function() {
var Rivets, jQuery,
 __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
 __slice = [].slice,
 __hasProp = {}.hasOwnProperty,
 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

Rivets = {};

jQuery = window.jQuery || window.Zepto;

if (!String.prototype.trim) {
 String.prototype.trim = function() {
   return this.replace(/^\s+|\s+$/g, '');
 };
}

Rivets.Binding = (function() {
 function Binding(view, el, type, key, keypath, options) {
   var identifier, regexp, value, _ref;
   this.view = view;
   this.el = el;
   this.type = type;
   this.key = key;
   this.keypath = keypath;
   this.options = options != null ? options : {};
   this.update = __bind(this.update, this);
   this.unbind = __bind(this.unbind, this);
   this.bind = __bind(this.bind, this);
   this.publish = __bind(this.publish, this);
   this.sync = __bind(this.sync, this);
   this.set = __bind(this.set, this);
   this.eventHandler = __bind(this.eventHandler, this);
   this.formattedValue = __bind(this.formattedValue, this);
   if (!(this.binder = this.view.binders[type])) {
     _ref = this.view.binders;
     for (identifier in _ref) {
       value = _ref[identifier];
       if (identifier !== '*' && identifier.indexOf('*') !== -1) {
         regexp = new RegExp("^" + (identifier.replace('*', '.+')) + "$");
         if (regexp.test(type)) {
           this.binder = value;
           this.args = new RegExp("^" + (identifier.replace('*', '(.+)')) + "$").exec(type);
           this.args.shift();
         }
       }
     }
   }
   this.binder || (this.binder = this.view.binders['*']);
   if (this.binder instanceof Function) {
     this.binder = {
       routine: this.binder
     };
   }
   this.formatters = this.options.formatters || [];
   this.model = this.key ? this.view.models[this.key] : this.view.models;
 }

 Binding.prototype.formattedValue = function(value) {
   var args, formatter, id, _i, _len, _ref;
   _ref = this.formatters;
   for (_i = 0, _len = _ref.length; _i < _len; _i++) {
     formatter = _ref[_i];
     args = formatter.split(/\s+/);
     id = args.shift();
     formatter = this.model[id] instanceof Function ? this.model[id] : this.view.formatters[id];
     if ((formatter != null ? formatter.read : void 0) instanceof Function) {
       value = formatter.read.apply(formatter, [value].concat(__slice.call(args)));
     } else if (formatter instanceof Function) {
       value = formatter.apply(null, [value].concat(__slice.call(args)));
     }
   }
   return value;
 };

 Binding.prototype.eventHandler = function(fn) {
   var binding, handler;
   handler = (binding = this).view.config.handler;
   return function(ev) {
     return handler.call(fn, this, ev, binding);
   };
 };

 Binding.prototype.set = function(value) {
   var _ref;
   value = value instanceof Function && !this.binder["function"] ? this.formattedValue(value.call(this.model)) : this.formattedValue(value);
   return (_ref = this.binder.routine) != null ? _ref.call(this, this.el, value) : void 0;
 };

 Binding.prototype.sync = function() {
   return this.set(this.options.bypass ? this.model[this.keypath] : this.view.config.adapter.read(this.model, this.keypath));
 };

 Binding.prototype.publish = function() {
   var args, formatter, id, value, _i, _len, _ref, _ref1, _ref2;
   value = Rivets.Util.getInputValue(this.el);
   _ref = this.formatters.slice(0).reverse();
   for (_i = 0, _len = _ref.length; _i < _len; _i++) {
     formatter = _ref[_i];
     args = formatter.split(/\s+/);
     id = args.shift();
     if ((_ref1 = this.view.formatters[id]) != null ? _ref1.publish : void 0) {
       value = (_ref2 = this.view.formatters[id]).publish.apply(_ref2, [value].concat(__slice.call(args)));
     }
   }
   return this.view.config.adapter.publish(this.model, this.keypath, value);
 };

 Binding.prototype.bind = function() {
   var dependency, keypath, model, _i, _len, _ref, _ref1, _ref2, _results;
   if ((_ref = this.binder.bind) != null) {
     _ref.call(this, this.el);
   }
   if (this.options.bypass) {
     this.sync();
   } else {
     this.view.config.adapter.subscribe(this.model, this.keypath, this.sync);
     if (this.view.config.preloadData) {
       this.sync();
     }
   }
   if ((_ref1 = this.options.dependencies) != null ? _ref1.length : void 0) {
     _ref2 = this.options.dependencies;
     _results = [];
     for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
       dependency = _ref2[_i];
       if (/^\./.test(dependency)) {
         model = this.model;
         keypath = dependency.substr(1);
       } else {
         dependency = dependency.split('.');
         model = this.view.models[dependency.shift()];
         keypath = dependency.join('.');
       }
       _results.push(this.view.config.adapter.subscribe(model, keypath, this.sync));
     }
     return _results;
   }
 };

 Binding.prototype.unbind = function() {
   var dependency, keypath, model, _i, _len, _ref, _ref1, _ref2, _results;
   if ((_ref = this.binder.unbind) != null) {
     _ref.call(this, this.el);
   }
   if (!this.options.bypass) {
     this.view.config.adapter.unsubscribe(this.model, this.keypath, this.sync);
   }
   if ((_ref1 = this.options.dependencies) != null ? _ref1.length : void 0) {
     _ref2 = this.options.dependencies;
     _results = [];
     for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
       dependency = _ref2[_i];
       if (/^\./.test(dependency)) {
         model = this.model;
         keypath = dependency.substr(1);
       } else {
         dependency = dependency.split('.');
         model = this.view.models[dependency.shift()];
         keypath = dependency.join('.');
       }
       _results.push(this.view.config.adapter.unsubscribe(model, keypath, this.sync));
     }
     return _results;
   }
 };

 Binding.prototype.update = function(models) {
   var _ref;
   if (models == null) {
     models = {};
   }
   if (this.key) {
     if (models[this.key]) {
       if (!this.options.bypass) {
         this.view.config.adapter.unsubscribe(this.model, this.keypath, this.sync);
       }
       this.model = models[this.key];
       if (this.options.bypass) {
         this.sync();
       } else {
         this.view.config.adapter.subscribe(this.model, this.keypath, this.sync);
         if (this.view.config.preloadData) {
           this.sync();
         }
       }
     }
   } else {
     this.sync();
   }
   return (_ref = this.binder.update) != null ? _ref.call(this, models) : void 0;
 };

 return Binding;

})();

Rivets.ComponentBinding = (function(_super) {
 __extends(ComponentBinding, _super);

 function ComponentBinding(view, el, type) {
   var attribute, _i, _len, _ref, _ref1;
   this.view = view;
   this.el = el;
   this.type = type;
   this.unbind = __bind(this.unbind, this);
   this.bind = __bind(this.bind, this);
   this.update = __bind(this.update, this);
   this.locals = __bind(this.locals, this);
   this.component = Rivets.components[this.type];
   this.attributes = {};
   this.inflections = {};
   _ref = this.el.attributes || [];
   for (_i = 0, _len = _ref.length; _i < _len; _i++) {
     attribute = _ref[_i];
     if (_ref1 = attribute.name, __indexOf.call(this.component.attributes, _ref1) >= 0) {
       this.attributes[attribute.name] = attribute.value;
     } else {
       this.inflections[attribute.name] = attribute.value;
     }
   }
 }

 ComponentBinding.prototype.sync = function() {};

 ComponentBinding.prototype.locals = function(models) {
   var inverse, key, model, path, result, _i, _len, _ref, _ref1;
   if (models == null) {
     models = this.view.models;
   }
   result = {};
   _ref = this.inflections;
   for (key in _ref) {
     inverse = _ref[key];
     _ref1 = inverse.split('.');
     for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
       path = _ref1[_i];
       result[key] = (result[key] || models)[path];
     }
   }
   for (key in models) {
     model = models[key];
     if (result[key] == null) {
       result[key] = model;
     }
   }
   return result;
 };

 ComponentBinding.prototype.update = function(models) {
   var _ref;
   return (_ref = this.componentView) != null ? _ref.update(this.locals(models)) : void 0;
 };

 ComponentBinding.prototype.bind = function() {
   var el, _ref;
   if (this.componentView != null) {
     return (_ref = this.componentView) != null ? _ref.bind() : void 0;
   } else {
     el = this.component.build.call(this.attributes);
     (this.componentView = new Rivets.View(el, this.locals(), this.view.options)).bind();
     return this.el.parentNode.replaceChild(el, this.el);
   }
 };

 ComponentBinding.prototype.unbind = function() {
   var _ref;
   return (_ref = this.componentView) != null ? _ref.unbind() : void 0;
 };

 return ComponentBinding;

})(Rivets.Binding);

Rivets.TextBinding = (function(_super) {
 __extends(TextBinding, _super);

 function TextBinding(view, el, type, key, keypath, options) {
   this.view = view;
   this.el = el;
   this.type = type;
   this.key = key;
   this.keypath = keypath;
   this.options = options != null ? options : {};
   this.sync = __bind(this.sync, this);
   this.formatters = this.options.formatters || [];
   this.model = this.key ? this.view.models[this.key] : this.view.models;
 }

 TextBinding.prototype.binder = {
   routine: function(node, value) {
     return node.data = value != null ? value : '';
   }
 };

 TextBinding.prototype.sync = function() {
   return TextBinding.__super__.sync.apply(this, arguments);
 };

 return TextBinding;

})(Rivets.Binding);

Rivets.View = (function() {
 function View(els, models, options) {
   var k, option, v, _base, _i, _len, _ref, _ref1, _ref2;
   this.els = els;
   this.models = models;
   this.options = options != null ? options : {};
   this.update = __bind(this.update, this);
   this.publish = __bind(this.publish, this);
   this.sync = __bind(this.sync, this);
   this.unbind = __bind(this.unbind, this);
   this.bind = __bind(this.bind, this);
   this.select = __bind(this.select, this);
   this.build = __bind(this.build, this);
   this.componentRegExp = __bind(this.componentRegExp, this);
   this.bindingRegExp = __bind(this.bindingRegExp, this);
   if (typeof this.els.length === 'undefined') {
     this.els = [this.els];
   }
   _ref = ['config', 'binders', 'formatters'];
   for (_i = 0, _len = _ref.length; _i < _len; _i++) {
     option = _ref[_i];
     this[option] = {};
     if (this.options[option]) {
       _ref1 = this.options[option];
       for (k in _ref1) {
         v = _ref1[k];
         this[option][k] = v;
       }
     }
     _ref2 = Rivets[option];
     for (k in _ref2) {
       v = _ref2[k];
       if ((_base = this[option])[k] == null) {
         _base[k] = v;
       }
     }
   }
   this.build();
 }

 View.prototype.bindingRegExp = function() {
   var prefix;
   prefix = this.config.prefix;
   if (prefix) {
     return new RegExp("^data-" + prefix + "-");
   } else {
     return /^data-/;
   }
 };

 View.prototype.componentRegExp = function() {
   var _ref, _ref1;
   return new RegExp("^" + ((_ref = (_ref1 = this.config.prefix) != null ? _ref1.toUpperCase() : void 0) != null ? _ref : 'RV') + "-");
 };

 View.prototype.build = function() {
   var bindingRegExp, buildBinding, componentRegExp, el, parse, skipNodes, _i, _len, _ref,
     _this = this;
   this.bindings = [];
   skipNodes = [];
   bindingRegExp = this.bindingRegExp();
   componentRegExp = this.componentRegExp();
   buildBinding = function(binding, node, type, declaration) {
     var context, ctx, dependencies, key, keypath, options, path, pipe, pipes, splitPath;
     options = {};
     pipes = (function() {
       var _i, _len, _ref, _results;
       _ref = declaration.split('|');
       _results = [];
       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         pipe = _ref[_i];
         _results.push(pipe.trim());
       }
       return _results;
     })();
     context = (function() {
       var _i, _len, _ref, _results;
       _ref = pipes.shift().split('<');
       _results = [];
       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         ctx = _ref[_i];
         _results.push(ctx.trim());
       }
       return _results;
     })();
     path = context.shift();
     splitPath = path.split(/\.|:/);
     options.formatters = pipes;
     options.bypass = path.indexOf(':') !== -1;
     if (splitPath[0]) {
       key = splitPath.shift();
     } else {
       key = null;
       splitPath.shift();
     }
     keypath = splitPath.join('.');
     if (dependencies = context.shift()) {
       options.dependencies = dependencies.split(/\s+/);
     }
     return _this.bindings.push(new Rivets[binding](_this, node, type, key, keypath, options));
   };
   parse = function(node) {
     var attribute, attributes, binder, childNode, delimiters, identifier, n, parser, regexp, restTokens, startToken, text, token, tokens, type, value, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4, _results;
     if (__indexOf.call(skipNodes, node) < 0) {
       if (node.nodeType === Node.TEXT_NODE) {
         parser = Rivets.TextTemplateParser;
         if (delimiters = _this.config.templateDelimiters) {
           if ((tokens = parser.parse(node.data, delimiters)).length) {
             if (!(tokens.length === 1 && tokens[0].type === parser.types.text)) {
               startToken = tokens[0], restTokens = 2 <= tokens.length ? __slice.call(tokens, 1) : [];
               node.data = startToken.value;
               if (startToken.type === 0) {
                 node.data = startToken.value;
               } else {
                 buildBinding('TextBinding', node, null, startToken.value);
               }
               for (_i = 0, _len = restTokens.length; _i < _len; _i++) {
                 token = restTokens[_i];
                 text = document.createTextNode(token.value);
                 node.parentNode.appendChild(text);
                 if (token.type === 1) {
                   buildBinding('TextBinding', text, null, token.value);
                 }
               }
             }
           }
         }
       } else if (componentRegExp.test(node.tagName)) {
         type = node.tagName.replace(componentRegExp, '').toLowerCase();
         _this.bindings.push(new Rivets.ComponentBinding(_this, node, type));
       } else if (node.attributes != null) {
         _ref = node.attributes;
         for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
           attribute = _ref[_j];
           if (bindingRegExp.test(attribute.name)) {
             type = attribute.name.replace(bindingRegExp, '');
             if (!(binder = _this.binders[type])) {
               _ref1 = _this.binders;
               for (identifier in _ref1) {
                 value = _ref1[identifier];
                 if (identifier !== '*' && identifier.indexOf('*') !== -1) {
                   regexp = new RegExp("^" + (identifier.replace('*', '.+')) + "$");
                   if (regexp.test(type)) {
                     binder = value;
                   }
                 }
               }
             }
             binder || (binder = _this.binders['*']);
             if (binder.block) {
               _ref2 = node.childNodes;
               for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
                 n = _ref2[_k];
                 skipNodes.push(n);
               }
               attributes = [attribute];
             }
           }
         }
         _ref3 = attributes || node.attributes;
         for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
           attribute = _ref3[_l];
           if (bindingRegExp.test(attribute.name)) {
             type = attribute.name.replace(bindingRegExp, '');
             buildBinding('Binding', node, type, attribute.value);
           }
         }
       }
       _ref4 = node.childNodes;
       _results = [];
       for (_m = 0, _len4 = _ref4.length; _m < _len4; _m++) {
         childNode = _ref4[_m];
         _results.push(parse(childNode));
       }
       return _results;
     }
   };
   _ref = this.els;
   for (_i = 0, _len = _ref.length; _i < _len; _i++) {
     el = _ref[_i];
     parse(el);
   }
 };

 View.prototype.select = function(fn) {
   var binding, _i, _len, _ref, _results;
   _ref = this.bindings;
   _results = [];
   for (_i = 0, _len = _ref.length; _i < _len; _i++) {
     binding = _ref[_i];
     if (fn(binding)) {
       _results.push(binding);
     }
   }
   return _results;
 };

 View.prototype.bind = function() {
   var binding, _i, _len, _ref, _results;
   _ref = this.bindings;
   _results = [];
   for (_i = 0, _len = _ref.length; _i < _len; _i++) {
     binding = _ref[_i];
     _results.push(binding.bind());
   }
   return _results;
 };

 View.prototype.unbind = function() {
   var binding, _i, _len, _ref, _results;
   _ref = this.bindings;
   _results = [];
   for (_i = 0, _len = _ref.length; _i < _len; _i++) {
     binding = _ref[_i];
     _results.push(binding.unbind());
   }
   return _results;
 };

 View.prototype.sync = function() {
   var binding, _i, _len, _ref, _results;
   _ref = this.bindings;
   _results = [];
   for (_i = 0, _len = _ref.length; _i < _len; _i++) {
     binding = _ref[_i];
     _results.push(binding.sync());
   }
   return _results;
 };

 View.prototype.publish = function() {
   var binding, _i, _len, _ref, _results;
   _ref = this.select(function(b) {
     return b.binder.publishes;
   });
   _results = [];
   for (_i = 0, _len = _ref.length; _i < _len; _i++) {
     binding = _ref[_i];
     _results.push(binding.publish());
   }
   return _results;
 };

 View.prototype.update = function(models) {
   var binding, key, model, _i, _len, _ref, _results;
   if (models == null) {
     models = {};
   }
   for (key in models) {
     model = models[key];
     this.models[key] = model;
   }
   _ref = this.bindings;
   _results = [];
   for (_i = 0, _len = _ref.length; _i < _len; _i++) {
     binding = _ref[_i];
     _results.push(binding.update(models));
   }
   return _results;
 };

 return View;

})();

Rivets.TextTemplateParser = (function() {
 function TextTemplateParser() {}

 TextTemplateParser.types = {
   text: 0,
   binding: 1
 };

 TextTemplateParser.parse = function(template, delimiters) {
   var index, lastIndex, lastToken, length, substring, tokens, value;
   tokens = [];
   length = template.length;
   index = 0;
   lastIndex = 0;
   while (lastIndex < length) {
     index = template.indexOf(delimiters[0], lastIndex);
     if (index < 0) {
       tokens.push({
         type: this.types.text,
         value: template.slice(lastIndex)
       });
       break;
     } else {
       if (index > 0 && lastIndex < index) {
         tokens.push({
           type: this.types.text,
           value: template.slice(lastIndex, index)
         });
       }
       lastIndex = index + 2;
       index = template.indexOf(delimiters[1], lastIndex);
       if (index < 0) {
         substring = template.slice(lastIndex - 2);
         lastToken = tokens[tokens.length - 1];
         if ((lastToken != null ? lastToken.type : void 0) === this.types.text) {
           lastToken.value += substring;
         } else {
           tokens.push({
             type: this.types.text,
             value: substring
           });
         }
         break;
       }
       value = template.slice(lastIndex, index).trim();
       tokens.push({
         type: this.types.binding,
         value: value
       });
       lastIndex = index + 2;
     }
   }
   return tokens;
 };

 return TextTemplateParser;

})();

Rivets.Util = {
 bindEvent: function(el, event, handler) {
   if (window.jQuery != null) {
     el = jQuery(el);
     if (el.on != null) {
       return el.on(event, handler);
     } else {
       return el.bind(event, handler);
     }
   } else if (window.addEventListener != null) {
     return el.addEventListener(event, handler, false);
   } else {
     event = 'on' + event;
     return el.attachEvent(event, handler);
   }
 },
 unbindEvent: function(el, event, handler) {
   if (window.jQuery != null) {
     el = jQuery(el);
     if (el.off != null) {
       return el.off(event, handler);
     } else {
       return el.unbind(event, handler);
     }
   } else if (window.removeEventListener != null) {
     return el.removeEventListener(event, handler, false);
   } else {
     event = 'on' + event;
     return el.detachEvent(event, handler);
   }
 },
 getInputValue: function(el) {
   var o, _i, _len, _results;
   if (window.jQuery != null) {
     el = jQuery(el);
     switch (el[0].type) {
       case 'checkbox':
         return el.is(':checked');
       default:
         return el.val();
     }
   } else {
     switch (el.type) {
       case 'checkbox':
         return el.checked;
       case 'select-multiple':
         _results = [];
         for (_i = 0, _len = el.length; _i < _len; _i++) {
           o = el[_i];
           if (o.selected) {
             _results.push(o.value);
           }
         }
         return _results;
         break;
       default:
         return el.value;
     }
   }
 }
};

Rivets.binders = {
 enabled: function(el, value) {
   return el.disabled = !value;
 },
 disabled: function(el, value) {
   return el.disabled = !!value;
 },
 checked: {
   publishes: true,
   bind: function(el) {
     return Rivets.Util.bindEvent(el, 'change', this.publish);
   },
   unbind: function(el) {
     return Rivets.Util.unbindEvent(el, 'change', this.publish);
   },
   routine: function(el, value) {
     var _ref;
     if (el.type === 'radio') {
       return el.checked = ((_ref = el.value) != null ? _ref.toString() : void 0) === (value != null ? value.toString() : void 0);
     } else {
       return el.checked = !!value;
     }
   }
 },
 unchecked: {
   publishes: true,
   bind: function(el) {
     return Rivets.Util.bindEvent(el, 'change', this.publish);
   },
   unbind: function(el) {
     return Rivets.Util.unbindEvent(el, 'change', this.publish);
   },
   routine: function(el, value) {
     var _ref;
     if (el.type === 'radio') {
       return el.checked = ((_ref = el.value) != null ? _ref.toString() : void 0) !== (value != null ? value.toString() : void 0);
     } else {
       return el.checked = !value;
     }
   }
 },
 show: function(el, value) {
   return el.style.display = value ? '' : 'none';
 },
 hide: function(el, value) {
   return el.style.display = value ? 'none' : '';
 },
 html: function(el, value) {
   return el.innerHTML = value != null ? value : '';
 },
 value: {
   publishes: true,
   bind: function(el) {
     return Rivets.Util.bindEvent(el, 'change', this.publish);
   },
   unbind: function(el) {
     return Rivets.Util.unbindEvent(el, 'change', this.publish);
   },
   routine: function(el, value) {
     var o, _i, _len, _ref, _ref1, _ref2, _results;
     if (window.jQuery != null) {
       el = jQuery(el);
       if ((value != null ? value.toString() : void 0) !== ((_ref = el.val()) != null ? _ref.toString() : void 0)) {
         return el.val(value != null ? value : '');
       }
     } else {
       if (el.type === 'select-multiple') {
         if (value != null) {
           _results = [];
           for (_i = 0, _len = el.length; _i < _len; _i++) {
             o = el[_i];
             _results.push(o.selected = (_ref1 = o.value, __indexOf.call(value, _ref1) >= 0));
           }
           return _results;
         }
       } else if ((value != null ? value.toString() : void 0) !== ((_ref2 = el.value) != null ? _ref2.toString() : void 0)) {
         return el.value = value != null ? value : '';
       }
     }
   }
 },
 text: function(el, value) {
   if (el.innerText != null) {
     return el.innerText = value != null ? value : '';
   } else {
     return el.textContent = value != null ? value : '';
   }
 },
 "if": {
   block: true,
   bind: function(el) {
     var attr, declaration;
     if (this.marker == null) {
       attr = ['data', this.view.config.prefix, this.type].join('-').replace('--', '-');
       declaration = el.getAttribute(attr);
       this.marker = document.createComment(" rivets: " + this.type + " " + declaration + " ");
       el.removeAttribute(attr);
       el.parentNode.insertBefore(this.marker, el);
       return el.parentNode.removeChild(el);
     }
   },
   unbind: function() {
     var _ref;
     return (_ref = this.nested) != null ? _ref.unbind() : void 0;
   },
   routine: function(el, value) {
     var key, model, models, options, _ref;
     if (!!value === (this.nested == null)) {
       if (value) {
         models = {};
         _ref = this.view.models;
         for (key in _ref) {
           model = _ref[key];
           models[key] = model;
         }
         options = {
           binders: this.view.options.binders,
           formatters: this.view.options.formatters,
           config: this.view.options.config
         };
         (this.nested = new Rivets.View(el, models, options)).bind();
         return this.marker.parentNode.insertBefore(el, this.marker.nextSibling);
       } else {
         el.parentNode.removeChild(el);
         this.nested.unbind();
         return delete this.nested;
       }
     }
   },
   update: function(models) {
     var _ref;
     return (_ref = this.nested) != null ? _ref.update(models) : void 0;
   }
 },
 unless: {
   block: true,
   bind: function(el) {
     return Rivets.binders["if"].bind.call(this, el);
   },
   unbind: function() {
     return Rivets.binders["if"].unbind.call(this);
   },
   routine: function(el, value) {
     return Rivets.binders["if"].routine.call(this, el, !value);
   },
   update: function(models) {
     return Rivets.binders["if"].update.call(this, models);
   }
 },
 "on-*": {
   "function": true,
   unbind: function(el) {
     if (this.handler) {
       return Rivets.Util.unbindEvent(el, this.args[0], this.handler);
     }
   },
   routine: function(el, value) {
     if (this.handler) {
       Rivets.Util.unbindEvent(el, this.args[0], this.handler);
     }
     return Rivets.Util.bindEvent(el, this.args[0], this.handler = this.eventHandler(value));
   }
 },
 "each-*": {
   block: true,
   bind: function(el) {
     var attr;
     if (this.marker == null) {
       attr = ['data', this.view.config.prefix, this.type].join('-').replace('--', '-');
       this.marker = document.createComment(" rivets: " + this.type + " ");
       this.iterated = [];
       el.removeAttribute(attr);
       el.parentNode.insertBefore(this.marker, el);
       return el.parentNode.removeChild(el);
     }
   },
   unbind: function(el) {
     var view, _i, _len, _ref, _results;
     if (this.iterated != null) {
       _ref = this.iterated;
       _results = [];
       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         view = _ref[_i];
         _results.push(view.unbind());
       }
       return _results;
     }
   },
   routine: function(el, collection) {
     var data, i, index, k, key, model, modelName, options, previous, template, v, view, _i, _j, _len, _len1, _ref, _ref1, _ref2, _results;
     modelName = this.args[0];
     collection = collection || [];
     if (this.iterated.length > collection.length) {
       _ref = Array(this.iterated.length - collection.length);
       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         i = _ref[_i];
         view = this.iterated.pop();
         view.unbind();
         this.marker.parentNode.removeChild(view.els[0]);
       }
     }
     _results = [];
     for (index = _j = 0, _len1 = collection.length; _j < _len1; index = ++_j) {
       model = collection[index];
       data = {};
       data[modelName] = model;
       if (this.iterated[index] == null) {
         _ref1 = this.view.models;
         for (key in _ref1) {
           model = _ref1[key];
           if (data[key] == null) {
             data[key] = model;
           }
         }
         previous = this.iterated.length ? this.iterated[this.iterated.length - 1].els[0] : this.marker;
         options = {
           binders: this.view.options.binders,
           formatters: this.view.options.formatters,
           config: {}
         };
         _ref2 = this.view.options.config;
         for (k in _ref2) {
           v = _ref2[k];
           options.config[k] = v;
         }
         options.config.preloadData = true;
         template = el.cloneNode(true);
         view = new Rivets.View(template, data, options);
         view.bind();
         this.iterated.push(view);
         _results.push(this.marker.parentNode.insertBefore(template, previous.nextSibling));
       } else if (this.iterated[index].models[modelName] !== model) {
         _results.push(this.iterated[index].update(data));
       } else {
         _results.push(void 0);
       }
     }
     return _results;
   },
   update: function(models) {
     var data, key, model, view, _i, _len, _ref, _results;
     data = {};
     for (key in models) {
       model = models[key];
       if (key !== this.args[0]) {
         data[key] = model;
       }
     }
     _ref = this.iterated;
     _results = [];
     for (_i = 0, _len = _ref.length; _i < _len; _i++) {
       view = _ref[_i];
       _results.push(view.update(data));
     }
     return _results;
   }
 },
 "class-*": function(el, value) {
   var elClass;
   elClass = " " + el.className + " ";
   if (!value === (elClass.indexOf(" " + this.args[0] + " ") !== -1)) {
     return el.className = value ? "" + el.className + " " + this.args[0] : elClass.replace(" " + this.args[0] + " ", ' ').trim();
   }
 },
 "*": function(el, value) {
   if (value) {
     return el.setAttribute(this.type, value);
   } else {
     return el.removeAttribute(this.type);
   }
 }
};

Rivets.components = {};

Rivets.config = {
 preloadData: true,
 handler: function(context, ev, binding) {
   return this.call(context, ev, binding.view.models);
 }
};

Rivets.formatters = {};

Rivets.factory = function(exports) {
 exports._ = Rivets;
 exports.binders = Rivets.binders;
 exports.components = Rivets.components;
 exports.formatters = Rivets.formatters;
 exports.config = Rivets.config;
 exports.configure = function(options) {
   var property, value;
   if (options == null) {
     options = {};
   }
   for (property in options) {
     value = options[property];
     Rivets.config[property] = value;
   }
 };
 return exports.bind = function(el, models, options) {
   var view;
   if (models == null) {
     models = {};
   }
   if (options == null) {
     options = {};
   }
   view = new Rivets.View(el, models, options);
   view.bind();
   return view;
 };
};

if (typeof exports === 'object') {
 Rivets.factory(exports);
} else if (typeof define === 'function' && define.amd) {
 define(['exports'], function(exports) {
   Rivets.factory(this.rivets = exports);
   return exports;
 });
} else {
 Rivets.factory(this.rivets = {});
}

}).call(this);
